home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Environments
/
RAMSES 2.2
/
RAMSES 2.2
/
M2Lib
/
HighInOut.MOD
< prev
next >
Wrap
Text File
|
1996-06-21
|
11KB
|
422 lines
IMPLEMENTATION MODULE HighInOut ;
(*
Implementation and Revisions:
============================
Author Date Description
------ ---- -----------
af 21/09/90 First implementation (DM 2.01,
MacMETH 2.6+)
af 02/10/90 curRP and curWP plus redirection
mechanism added
*)
IMPORT Terminal; (* just for Read, Write, and WriteLn *)
FROM Conversions IMPORT StringToReal, RealToFixString;
(* is too complicated to implement here *)
CONST
EOL = 15C; (* Return on Mac *)
LF = 12C;
CAN = 30C;
ESC = 33C;
HELP = "?";
BS = 10C;
BEL = 7C;
DEL = 177C;
VAR
RandomWriteDisplay: BOOLEAN;
curGiveHelp: PROC;
curRP: ReadProc;
curWP: WriteProc;
curWLnP: WriteLnProc;
VAR
readAgainFlag: BOOLEAN;
PROCEDURE Read (VAR ch: CHAR);
BEGIN
IF readAgainFlag THEN
ch := termCH;
readAgainFlag := FALSE;
ELSE
curRP(termCH); ch := termCH;
END(*IF*);
Aborted := ch = ESC;
END Read;
PROCEDURE ReadAgain;
BEGIN
readAgainFlag := TRUE;
END ReadAgain;
PROCEDURE Write (ch: CHAR);
PROCEDURE SysBeep(duration: INTEGER); CODE 0A9C8H;
BEGIN
IF ch=BEL THEN
SysBeep(1);
ELSE
curWP(ch);
END(*IF*);
END Write;
PROCEDURE WriteLn;
BEGIN
curWLnP;
END WriteLn;
PROCEDURE ReadString(VAR s: ARRAY OF CHAR);
VAR
ch: CHAR;
i,wrpos: CARDINAL;
BEGIN (*ReadString*)
Done:=TRUE;
REPEAT Read(ch); UNTIL (ch>" ") OR (ch=ESC) OR (ch=CAN);
wrpos:=0;
i:=0;
LOOP
IF (ch=DEL) OR (ch=BS) THEN
IF i>0 THEN DEC(i); s[i]:=" " END;
IF wrpos>0 THEN
Write(DEL); DEC(wrpos)
END(*IF*);
ELSIF (ch=ESC) OR (ch=CAN) OR (ch<" ") THEN
termCH:=ch; Done:=FALSE; EXIT
ELSE
IF i<=HIGH(s) THEN s[i]:=ch END;
i:=i+1;
Write(ch); INC(wrpos);
END(*IF*);
Read(ch);
END(*LOOP*);
IF i<=HIGH(s) THEN s[i]:=0C END;
END ReadString;
PROCEDURE ReadInt(VAR x: INTEGER);
VAR i: INTEGER; n: CARDINAL;
ch: CHAR; neg: BOOLEAN;
buf: ARRAY [0..9] OF CHAR;
PROCEDURE next;
BEGIN ch := buf[n]; n := n+1
END next;
BEGIN
ReadString(buf); n := 0; next;
WHILE ch = " " DO next END ;
IF ch = "-" THEN
neg := TRUE; next
ELSE neg := FALSE;
IF ch = "+" THEN next END
END ;
IF ("0" <= ch) & (ch <= "9") THEN
i := 0; Done := TRUE;
REPEAT i := 10*i + (ORD(ch) - ORD("0")); next
UNTIL (ch < "0") OR ("9" < ch);
Done:= Done AND (ch<=" ");
IF neg THEN x := -i ELSE x := i END
ELSE Done:= FALSE
END;
END ReadInt;
PROCEDURE ReadReal (VAR x: REAL);
VAR buf: ARRAY [0..25] OF CHAR;
BEGIN
ReadString(buf);
StringToReal(buf,0,x,Done);
END ReadReal;
PROCEDURE WriteString (s: ARRAY OF CHAR);
VAR i,n: INTEGER;
BEGIN
i:= 0; n:= HIGH(s);
WHILE (i<=n) AND (s[i]<>0C) DO
Write(s[i]); INC(i);
END(*WHILE*);
END WriteString;
PROCEDURE WriteInt(x: LONGINT; n: CARDINAL);
VAR i: CARDINAL; dig: INTEGER; x0: LONGINT;
a: ARRAY [0..12] OF CHAR;
BEGIN
i := 0; x0 := ABS(x);
REPEAT
dig := x0 MOD 10D; dig := dig + 60B;
a[i] := CHR(dig);
x0 := x0 DIV 10D; i := i+1
UNTIL x0 = 0D;
IF x < 0D THEN a[i] := "-"; i := i+1 END ;
WHILE n > i DO
n := n-1; Write(" ")
END ;
REPEAT i := i-1; Write(a[i]) UNTIL i = 0
END WriteInt;
PROCEDURE WriteReal (x: REAL; n,dec: CARDINAL);
VAR buf: ARRAY [0..80] OF CHAR; VAR dummyOk: BOOLEAN;
BEGIN
RealToFixString (x,dec,n,buf,dummyOk); (* should automatically
convert to exponential representation if number too large *)
WriteString(buf);
END WriteReal;
PROCEDURE Wait;
CONST t = "To continue hit a key";
VAR ch: CHAR;
BEGIN
IF RandomWriteDisplay THEN
(*. IF Row=maxRow THEN (*insert a line*) WriteLn END;
Write(BEL); moveCursor(maxRow,(maxCol-25(*length of t*)) DIV 2);
reverseOn; blinkingOn;
WriteString(t); Write(BS);
blinkingOff; reverseOff;
Read(ch); moveCursor(Row,1); eraseToEOL;
epr:=epr-ScrollUps;
moveCursor(epr,epc); eraseToEOL; moveCursor(epr,1); .*)
ELSE
Terminal.WriteString(t); Terminal.WriteString("… ");
Read(ch);
END(*IF RandomWriteDisplay*);
END Wait;
PROCEDURE DefaultGiveHelp;
CONST t = "no help information available";
VAR ch: CHAR;
BEGIN
IF RandomWriteDisplay THEN
(*. IF Row=maxRow THEN (*insert a line*) WriteLn END;
Write(BEL); moveCursor(maxRow,(maxCol-29(*length of t*)) DIV 2);
reverseOn; blinkingOn;
WriteString(t); Write(BS);
blinkingOff; reverseOff;
Read(ch); moveCursor(Row,1); eraseToEOL;
epr:=epr-ScrollUps;
moveCursor(epr,epc); eraseToEOL; moveCursor(epr,1); .*)
ELSE
WriteLn;
WriteString(t);
WriteLn;
END(*IF RandomWriteDisplay*);
END DefaultGiveHelp;
PROCEDURE InstallGiveHelpProc (hp: PROC);
BEGIN
curGiveHelp := hp;
END InstallGiveHelpProc;
CONST
askKeyStringLength=3;
TYPE
askKeyString=ARRAY[0..askKeyStringLength-1] OF CHAR;
VAR
yes,no: askKeyString;
PROCEDURE Ask(question: ARRAY OF CHAR; VAR affirmation: BOOLEAN);
VAR
i: CARDINAL;
s: askKeyString; les: CARDINAL;
sofarOK: BOOLEAN;
ch: CHAR;
BEGIN (*Ask*)
LOOP
WriteString(question);
(* random screen not supported: epr:=Row; epc:=Col; ScrollUps:=0; *)
Read(termCH);
IF termCH=EOL THEN
affirmation:=FALSE; Aborted:=FALSE;
WriteString(no); EXIT
ELSE
ReadAgain;
ReadString(s); (*s must be terminated by 0C if shorter than HIGH(s)*)
IF termCH=ESC THEN
WriteString("<ESC>");
affirmation:=FALSE;
Aborted:=TRUE;
EXIT
ELSIF termCH=CAN THEN
WriteString(" - cancelled!"); WriteLn; Wait;
ELSE
sofarOK:=TRUE;
i:=0;
WHILE (i<=askKeyStringLength-1) AND (s[i]<>0C) DO
ch:=CAP(s[i]);
sofarOK:=sofarOK AND ((ch=yes[i]) OR (ch=no[i]));
INC(i);
END(*WHILE*);
les:=i;
IF sofarOK THEN
affirmation:=CAP(s[0])="Y";
FOR i:=les TO askKeyStringLength-1 DO
IF affirmation
THEN Write(yes[i])
ELSE Write(no[i])
END(*IF*)
END(*FOR*);
Aborted:=FALSE;
EXIT
ELSE
Write(BEL);
WriteString(" --- illegal answer! Try 'y(es)' or 'n(o)'!");
WriteLn; Wait;
END(*IF sofarOK*);
END(*IF termCH=ESC*);
END(*IF first char entered = EOL*);
END(*LOOP*);
END Ask;
PROCEDURE PromptForChars(p: ARRAY OF CHAR; chs: ARRAY OF CHAR;
VAR ch: CHAR);
VAR s: ARRAY [0..2] OF CHAR;
PROCEDURE InChs(ch: CHAR): BOOLEAN;
VAR i,n: CARDINAL; q: BOOLEAN;
BEGIN
i:=0; n:=HIGH(chs);
WHILE i<=n DO IF ch=chs[i] THEN RETURN TRUE ELSE INC(i) END END;
RETURN FALSE;
END InChs;
BEGIN (*PromptForChars*)
REPEAT
WriteString(p);
(* random screen not supported: epr:=Row; epc:=Col; ScrollUps:=0; *)
ReadString(s);
IF NOT Done THEN
IF termCH=ESC THEN
WriteString("<ESC>"); Aborted:= TRUE; WriteLn;
ELSIF termCH=CAN THEN
WriteString(" - cancelled"); WriteLn; Wait; Aborted:=FALSE;
ELSE
Write(BEL); WriteString(" --- error occured: ");
WriteString("tried to read past end of file");
WriteLn; Aborted:=TRUE;
END(*IF ESC*);
ELSE
Aborted:=FALSE; ch:=s[0];
IF InChs(ch) THEN
(*RETURN with ch*)
ELSIF ch=HELP THEN curGiveHelp
ELSE
Write(BEL);
WriteString(" --- out of range; press one of ");
Write("'"); WriteString(chs); Write("'"); WriteLn; Wait;
Done:=FALSE;
END(*IF valid range*);
END(*IF not eof*);
UNTIL Done OR Aborted;
curGiveHelp:=DefaultGiveHelp;
END PromptForChars;
PROCEDURE PromptForInt(p: ARRAY OF CHAR; min,max: INTEGER; VAR x: INTEGER);
BEGIN (*PromptForInt*)
REPEAT
WriteString(p);
(* random screen not supported: epr:=Row; epc:=Col; ScrollUps:=0; *)
ReadInt(x);
IF NOT Done THEN
IF termCH=ESC THEN
WriteString("<ESC>"); Aborted:= TRUE; WriteLn;
ELSIF termCH=CAN THEN
WriteString(" - cancelled"); WriteLn; Wait;
ELSIF termCH=HELP THEN
curGiveHelp
ELSE
Write(BEL); WriteString(" --- illegal number; enter INTEGER");
WriteLn; Wait;
END(*IF ESC*);
ELSE
Aborted:=FALSE;
IF (min<=x) AND (x<=max) THEN
(*RETURN with x*)
ELSE
Write(BEL);
WriteString(" --- out of range; enter number within ");
WriteInt(min,0); WriteString(".."); WriteInt(max,0); WriteLn;
Wait; Done:=FALSE;
END(*IF valid range*);
END(*IF legal INTEGER*);
UNTIL Done OR Aborted;
curGiveHelp:=DefaultGiveHelp;
END PromptForInt;
PROCEDURE PromptForReal(p: ARRAY OF CHAR; min,max: REAL; VAR x: REAL);
BEGIN (*PromptForReal*)
REPEAT
WriteString(p);
(* random screen not supported: epr:=Row; epc:=Col; ScrollUps:=0; *)
ReadReal(x);
IF NOT Done THEN
IF termCH=ESC THEN
WriteString("<ESC>"); Aborted:= TRUE; WriteLn;
ELSIF termCH=CAN THEN
WriteString(" - cancelled"); WriteLn; Wait;
ELSIF termCH=HELP THEN
curGiveHelp
ELSE
Write(BEL); WriteString(" --- illegal number; enter REAL");
WriteLn; Wait;
END(*IF ESC*);
ELSE (*Done=TRUE*)
Aborted:=FALSE;
IF (min<=x) AND (x<=max) THEN
(*RETURN with x*)
ELSE
Write(BEL);
WriteString(" --- out of range; enter number within ");
WriteReal(min,0,5); WriteString(".."); WriteReal(max,0,5); WriteLn;
Wait; Done:=FALSE;
END(*IF valid range*);
END(*IF legal REAL*);
UNTIL Done OR Aborted;
curGiveHelp:=DefaultGiveHelp;
END PromptForReal;
PROCEDURE InstallReadProc (rp: ReadProc);
BEGIN
curRP := rp;
END InstallReadProc;
PROCEDURE InstallWriteProc (wp: WriteProc);
BEGIN
curWP := wp;
END InstallWriteProc;
PROCEDURE InstallWriteLnProc (wlnp: WriteLnProc);
BEGIN
curWLnP := wlnp
END InstallWriteLnProc;
BEGIN
termCH:= " "; Done:=FALSE; Aborted:=FALSE;
yes:="YES"; no:="NO ";
curRP := Terminal.Read;
curWP := Terminal.Write;
curWLnP := Terminal.WriteLn;
curGiveHelp:=DefaultGiveHelp;
(* no random, i.e. cursor controlled, screen output
supported in current implementation: *)
RandomWriteDisplay := FALSE;
END HighInOut .